<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 传入一个函数,将其改写为柯里化函数 
    // 传入的函数参数可以不受限制
    /* function currying(callback){
        var _args = []; // 用于存放所有参数(闭包)
        return function () { // 
            console.log(arguments); // [1]
            _args.push(...arguments); // Array.prototype.push.apply(_args,arguments);
            if(arguments.length == 0){  // 没有参数 最后一层 => 执行传入的回调函数
                console.log("最后一层",_args);
                // return callback(..._args);  // 如果参数传入完毕 => 调用原函数
                return callback.apply(null,_args);  // 如果参数传入完毕 => 调用原函数
            }
            return arguments.callee;
        }
    }

    function add(){
        var sum = 0;
        for(var i = 0;i<arguments.length;i++){
            var item = arguments[i];
            sum += item;
        }
        return sum;
    }


    var sum = currying(add);
    console.log(sum);


    // 此写法优点 => 传入的参数可以不受长度限制
    // 缺点:  最后要多加一个() => 不传参(arguments.length == 0) => 自动计算
    // var res = sum(1)(2)(3)();   // 三个参数
    // var res = sum(1)(2)(3)(4)(5)(6)();   // 6个参数
    var res = sum(1)(2)();   // 2个参数  =>  a:1  b:2  c:undefined  => NaN
    console.log("res",res); */


    // 优化版 => 期望函数结果不需要多加 () 


    function currying(callback) {  // 调用currying返回新函数
        return function () { //  新函数首次调用会返回func
            var _args = [...arguments]; // 用于存放所有参数(闭包)
            function func() { // 继续调用func => 返回func
                _args.push(...arguments);
                return func;
            }
            // func隐式转字符串时调用   
            func.toString = func.valueOf = function () {
                console.log("隐式转字符串",_args);
                console.log("隐式转字符串",callback(..._args));
                return callback(..._args);  // 计算最终的结果
                // return callback.apply(null,_args);
            }
            return func;
        }
    }

    function add() {
        var sum = 0;
        for (var i = 0; i < arguments.length; i++) {
            var item = arguments[i];
            sum += item;
        }
        return sum;
    }


    var sum = currying(add)
    // console.log(sum);

    var res = sum(1)(2)(3)(4); // res = func

    // 其实打印 res 已经触发了隐式转换  (先打印函数func , 在隐式转字符串 => 谷歌浏览器)  => 打印res时还是一个函数
    // console.log(res);

    // 怎么办?  => 各种方式触发隐式类型转换  (函数会优先调用valueOf 如果valueOf会将降级调用toString)
    console.log(res.toString());
    console.log(res * 1);
    console.log(res  ==  10); // true
    console.log(+res);  // 一元运算符  +1
    
    console.log(String(res));  // 
    console.log(Number(res));  // 






</script>

</html>